package cn.ultrarisk.scadmin.manager.biz.monitor.dao;

import cn.ultrarisk.mybatis.extension.query.Query;
import cn.ultrarisk.scadmin.manager.biz.monitor.entity.SolrCacheMonitor;
import cn.ultrarisk.scadmin.manager.biz.solr.context.SolrCacheType;
import cn.ultrarisk.scadmin.manager.support.BaseDAO;
import org.springframework.stereotype.Repository;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * solr缓存监控数据操作类
 *
 * @author sevendlong(lin23871@163.com)
 * @date 2014/3/28
 * @since V1.0
 */
@Repository
public class SolrCacheMonitorDAO extends BaseDAO<SolrCacheMonitor, Long> {
    /**
     * 构造器
     */
    public SolrCacheMonitorDAO() {
        super(SolrCacheMonitor.class, SolrCacheMonitor.COLUMN_PROPERTY_MAP);
    }

    public Map<Integer, SolrCacheMonitor> groupByReplicaId(long startTime, long endTime, SolrCacheType cacheType) {
        Query query = Query.gteQuery(SolrCacheMonitor.CREATE_TIME, startTime).lt(SolrCacheMonitor.CREATE_TIME, endTime);
        query.eq(SolrCacheMonitor.TYPE, cacheType);
        query.addGroup(SolrCacheMonitor.REPLICA_ID);
        return findMap(query, SolrCacheMonitor.REPLICA_ID, SolrCacheMonitor.NODE_ID, SolrCacheMonitor.COLLECTION_ID, SolrCacheMonitor.SHARD_ID, SolrCacheMonitor.REPLICA_ID);
    }

    public Map<SolrCacheMonitor, Long> getVisitCount(long startTime, long endTime) {
        Map<Integer, SolrCacheMonitor> monitorMap = groupByReplicaId(startTime, endTime, SolrCacheType.QUERY_RESULT_CACHE);

        Map<SolrCacheMonitor, Long> stat = new HashMap<SolrCacheMonitor, Long>();
        if (monitorMap != null && monitorMap.size() > 0) {
            Set<Integer> replicaIds = monitorMap.keySet();

            Query query = Query.gteQuery(SolrCacheMonitor.CREATE_TIME, startTime).lt(SolrCacheMonitor.CREATE_TIME, endTime);
            query.eq(SolrCacheMonitor.TYPE, SolrCacheType.QUERY_RESULT_CACHE);
            query.addSort(SolrCacheMonitor.CREATE_TIME, Query.Direction.DESC);
            query.addAttach("replicaIds", replicaIds);
            Map<String, Object> visitCountStat = sqlSessionTemplate.selectOne(entityName + ".visitCountStat", query.toMap(tableName));

            for (Integer replicaId : replicaIds) {
                SolrCacheMonitor monitor = monitorMap.get(replicaId);
                String key = "replica_" + replicaId;
                stat.put(monitor, Long.parseLong(visitCountStat.get(key).toString()));
            }
        }
        return stat;
    }

    public Map<SolrCacheMonitor, Map<String, Double>> getQPSStat(long startTime, long endTime) {
        Map<Integer, SolrCacheMonitor> monitorMap = groupByReplicaId(startTime, endTime, SolrCacheType.QUERY_RESULT_CACHE);

        Map<SolrCacheMonitor, Map<String, Double>> stat = new HashMap<SolrCacheMonitor, Map<String, Double>>();
        if (monitorMap != null && monitorMap.size() > 0) {
            Set<Integer> replicaIds = monitorMap.keySet();

            Query query = Query.gteQuery(SolrCacheMonitor.CREATE_TIME, startTime).lt(SolrCacheMonitor.CREATE_TIME, endTime);
            query.eq(SolrCacheMonitor.TYPE, SolrCacheType.QUERY_RESULT_CACHE);
            query.addSort(SolrCacheMonitor.CREATE_TIME, Query.Direction.DESC);
            query.addAttach("replicaIds", replicaIds);
            Map<String, Object> qpsAvgStat = sqlSessionTemplate.selectOne(entityName + ".qpsAvgStat", query.toMap(tableName));
            Map<String, Object> qpsMaxStat = sqlSessionTemplate.selectOne(entityName + ".qpsMaxStat", query.toMap(tableName));

            for (Integer replicaId : replicaIds) {
                SolrCacheMonitor monitor = monitorMap.get(replicaId);
                Map<String, Double> replicaQpsMap = new HashMap<String, Double>();

                String key = "replica_" + replicaId;
                if (qpsAvgStat != null && qpsAvgStat.get(key) != null) {
                    replicaQpsMap.put("avg", Double.parseDouble(qpsAvgStat.get(key).toString()));
                }
                if (qpsMaxStat != null && qpsMaxStat.get(key) != null) {
                    replicaQpsMap.put("max", Double.parseDouble(qpsMaxStat.get(key).toString()));
                }
                stat.put(monitor, replicaQpsMap);
            }
        }
        return stat;
    }

    public Map<SolrCacheMonitor, Double> getCacheStat(long startTime, long endTime) {
        Map<Integer, SolrCacheMonitor> monitorMap = groupByReplicaId(startTime, endTime, SolrCacheType.QUERY_RESULT_CACHE);

        if (monitorMap != null && monitorMap.size() > 0) {
            Query query = Query.gteQuery(SolrCacheMonitor.CREATE_TIME, startTime).lt(SolrCacheMonitor.CREATE_TIME, endTime);
            query.eq(SolrCacheMonitor.TYPE, SolrCacheType.QUERY_RESULT_CACHE);
            query.addSort(SolrCacheMonitor.CREATE_TIME, Query.Direction.DESC);
            query.addAttach("replicaIds", monitorMap.keySet());
            Map<String, Object> qpsStat = sqlSessionTemplate.selectOne(entityName + ".cacheStat", query.toMap(tableName));

            Map<SolrCacheMonitor, Double> stat = new HashMap<SolrCacheMonitor, Double>();
            if (qpsStat != null) {
                for (String key : qpsStat.keySet()) {
                    SolrCacheMonitor monitor = monitorMap.get(Integer.parseInt(key.replace("replica_", "")));
                    if (monitor != null) {
                        stat.put(monitor, Double.parseDouble(qpsStat.get(key).toString()));
                    }
                }
                return stat;
            }
        }
        return null;
    }
}
